# coding:utf-8
from numpy.fft.fftpack import fft, ifft
from numpy.ma.core import exp, log
from numpy.lib.function_base import append
from numpy.core.numeric import zeros, ones

class MinPhase(object):
    """最小位相を利用した残響抑圧
    """
    
    def __init__(self, ir):
        self.ir = ir
        while True:
            try:
                self.N = int(raw_input("DFT point length by even number (fmt: 1024 or 2**10) >>> "))
                if self.N % 2 != 0:
                    print "this number is not even. please retype."
                    continue
                break
            except:
                print "format may be wrong. please retype."
            
        
    def _calcCamp(self):
        """振幅ケプストラムを求める
        """
        H = fft(self.ir, self.N)
        camp = ifft(log(abs(H)), self.N).real
        return camp
    
    def _genWin(self):
        """リフタを得る
        """
        window = append(2 * ones([self.N / 2]), zeros(self.N / 2))
        window[:self.N / 2 + 1:self.N / 2].fill(1)
        return window
    
    def _calcAmp(self, campWin):
        """振幅ケプストラムにリフタを掛けたものから 残響抑圧後の時間信号を得る
        """
        lHmin = fft(campWin, self.N)
        Hmin = exp(lHmin)
        hmin = ifft(Hmin, self.N).real
        return hmin
    
    def calc(self):
        """メインルーチン
        """
        campWin = self._calcCamp()*self._genWin()
        hmin = self._calcAmp(campWin)
        return hmin
        